﻿#include "snake.h"

void pSnake_Inits(pSnake ps)
{
	ps->_pSnake = NULL;
	ps->_pFood = NULL;
	ps->_Dir = RIGHT;
	ps->_GameStatus = OK;
	ps->_Socre = 0;
	ps->_foodWeight = 0;
	ps->_SleepTime = 0;
}

void SetsPos(short x, short y)
{
	COORD pos = { x,y };
	HANDLE hOutput = NULL;
	//获取标准输出的句柄(用来标识不同设备的数值)
	hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	//设置标准输出上光标的位置为pos
	SetConsoleCursorPosition(hOutput, pos);

}

void WelcomeToGame()
{
	SetsPos(35, 12);
	wprintf(L"欢迎来贪吃蛇小游戏!");

	SetsPos(35, 20);
	system("pause");

	system("cls");

	SetsPos(20, 12);
	wprintf(L"用 ↑ . ↓ . ← . → 分别控制蛇的移动， F3为加速，F4为减速\n");

	SetsPos(35, 20);
	system("pause");
	system("cls");

}
void CreateMap()
{
	int i = 0;
	SetsPos(0, 0);
	//Sleep(1000);
	//上
	for (i = 0; i < 58; i+=2)
	{

		wprintf(WALL);
	}
	
	//下
	SetsPos(0, 26);
	for (i = 0; i < 58; i += 2)
	{

		wprintf(WALL);
	}

	//左
	for (i = 1; i < 26; i++)
	{
		SetsPos(0, i);
		wprintf(WALL);
	}
	 
	//右
	for (i = 1; i < 26; i++)
	{
		SetsPos(56, i);
		wprintf(WALL);
	}
	
}

void InitSnake(pSnake ps)
{
	int i = 0;
	pSnakeNode cur = NULL;
	//创建蛇节点
	for (i = 0; i < 5; i++)
	{
		cur = malloc(sizeof(SnakeNode));
		if (cur == NULL)
		{
			perror("mallco : cur");
			exit(1);
		}
		cur->next = NULL;
		cur->x = 24 + i * 2;
		cur->y = 5;
		if (ps->_pSnake==NULL)
		{
			ps->_pSnake = cur;
		}
		else
		{
			cur->next = ps->_pSnake;
			ps->_pSnake = cur;
		}
	}
	//打印蛇
	cur = ps->_pSnake;
	while (cur)
	{
		SetsPos(cur->x, cur->y);
		wprintf(SBODY);
		cur = cur->next;
	}
	ps->_pFood = NULL;
	ps->_Dir = RIGHT;
	ps->_GameStatus = OK;
	ps->_Socre = 0;
	ps->_foodWeight = 10;
	ps->_SleepTime = 200;
}
//创建食物
void CreateFood(pSnake ps)
{
	int x;
	int y;
	again:
	do {
		x = rand() % 53 + 2;
		y = rand() % 25 + 1;
	} while (x%2!=0);
	pSnakeNode cur = NULL;
	cur = ps->_pSnake;
	while(cur)
	{
		if (cur->x == x && cur->y == y)
		{
			goto again;
		}
		cur = cur->next;
	}

	cur = malloc(sizeof(SnakeNode));
	if (cur == NULL)
	{
		perror("malloc:pFOOD");
		exit(1);
	}
	cur->x = x;
	cur->y = y;
	cur->next = NULL;
	ps->_pFood = cur;
	SetsPos(ps->_pFood->x, ps->_pFood->y);
	cur = NULL;
	wprintf(SFOOD);
}
void GameStart(pSnake ps)
{
	setlocale(LC_ALL, "");//切换到本地环境
	//1.设置窗口大小
	system("mode con cols=100 lines=30");


	//2设置窗口名字
	system("title 贪吃蛇");

	//3.隐藏光标
	HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//获取标准输出的句柄(用来标识不同设备的数值)
	//影藏光标操作
	CONSOLE_CURSOR_INFO CursorInfo;
	GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息
	CursorInfo.bVisible = false; //隐藏控制台光标
	SetConsoleCursorInfo(hOutput, &CursorInfo);//设置控制台光标状态

	//4.打印欢迎界面- WelcomeToGame
	
	WelcomeToGame();

	
	//5.创建地图- CreateMap
	CreateMap();
	
	//6.初始化蛇身- InitSnake
	
	InitSnake(ps);


	//7.创建食物- CreateFood
	CreateFood(ps);

}
void PrintfHelP(pSnake ps)
{
	SetsPos(63, 9);
	printf("得分:%2d 每个食物得分:%2d", ps->_Socre, ps->_foodWeight);
	SetsPos(63, 12);
	printf("用↑.↓.←.→分别控制蛇的移动.");
	SetsPos(63, 15);
	printf("F1 为加速，F2 为减速\n");
	SetsPos(63, 18);
	printf("ESC ：退出游戏   space：暂停游戏.");
	SetsPos(63, 21);
	printf("@valan-liya");

}

void pause()
{
	while(1){
		Sleep(300);
		if (KEY_PRESS(VK_SPACE))
			break;
	}
}

//#define WALL L"□"
//#define SBODY L"●"
//#define SFOOD L"★"


int IFNEXT(pSnake ps, pSnakeNode cur)
{
	pSnakeNode tmp = ps->_pSnake;
	if (cur->x < 2 || cur->x > 55 || cur->y < 1 || cur->y > 25)
	{
		ps->_GameStatus = WALLS;
		return 1;

	}
	while (tmp)
	{
		if (tmp->x == cur->x && tmp->y == cur->y)
		{
			ps->_GameStatus = BITE;
			return 1;
		}
		tmp = tmp->next;
	}
	
}

void IFSNAKE(pSnake ps, pSnakeNode cur)
{
	cur->next = ps->_pSnake;
	ps->_pSnake = cur;
	SetsPos(cur->x, cur->y);
	wprintf(SBODY);
	cur = ps->_pSnake;
	while (cur->next->next)
	{
		cur = cur->next;
	}

	SetsPos(cur->next->x, cur->next->y);
	printf("  ");
	free(cur->next);
	cur->next = NULL;
}


void IFFOOD(pSnake ps, pSnakeNode cur)
{
	cur->next = ps->_pSnake;
	ps->_pSnake = cur;
	SetsPos(cur->x, cur->y);
	wprintf(SBODY);
	free(ps->_pFood);
	CreateFood(ps);
	ps->_Socre += ps->_foodWeight;

}




void SnakeMove(pSnake ps)
{
	pSnakeNode cur= malloc(sizeof(SnakeNode));

	if (cur == NULL)
	{

		perror("SnakeMove::malloc");
		exit(1);
	}
	if (ps->_Dir == RIGHT)
	{
		cur->x = ps->_pSnake->x + 2;
		cur->y = ps->_pSnake->y;
	}
	else if (ps->_Dir == LEFT)
	{
		cur->x = ps->_pSnake->x - 2;
		cur->y = ps->_pSnake->y;
	}
	else if (ps->_Dir == DOWN)
	{
		cur->x = ps->_pSnake->x;
		cur->y = ps->_pSnake->y+1;
	}
	else if (ps->_Dir == UP)
	{
		cur->x = ps->_pSnake->x;
		cur->y = ps->_pSnake->y - 1;
	}
	
	
	
	if (IFNEXT(ps, cur))
	{
	
		return;

	}
	
		
	if ((cur->x == ps->_pFood->x) && (cur->y == ps->_pFood->y))
	{
		IFFOOD(ps, cur);

	}
	else
	{
		IFSNAKE(ps, cur);

	}

}




void GameRun(pSnake ps)
{
	
	
//#define KEY_PRESS(VK) ((GetAsyncKeyState(VK)&0x1) ? 1 : 0)
	do {
		PrintfHelP(ps);

		if (KEY_PRESS(VK_LEFT) && (ps->_Dir != RIGHT))
		{
			ps->_Dir = LEFT;
		}
		else if (KEY_PRESS(VK_RIGHT) && (ps->_Dir != LEFT))
		{
			ps->_Dir = RIGHT;

		}
		else if (KEY_PRESS(VK_UP) && (ps->_Dir != DOWN))
		{
			ps->_Dir = UP;

		}
		else if (KEY_PRESS(VK_DOWN) && (ps->_Dir != UP))
		{
			ps->_Dir = DOWN;

		}
		else if (KEY_PRESS(VK_SPACE))
		{

			//SetsPos(25, 10);
			//printf("游戏暂停按spase解除！");
			pause();

		}
		else if (KEY_PRESS(VK_ESCAPE))
		{
			ps->_GameStatus = END;
		}
		//ps->_foodWeight = 10;
		//ps->_SleepTime = 200;
		else if (KEY_PRESS(VK_F1))
		{
			if (ps->_SleepTime > 40)
			{
				ps->_SleepTime -= 20;
				ps->_foodWeight += 5;
			}

		}
		else if (KEY_PRESS(VK_F2))
		{
			if (ps->_SleepTime < 240)
			{
				ps->_SleepTime += 20;
				ps->_foodWeight -= 5;
			}
		}
		Sleep(ps->_SleepTime);
		SnakeMove(ps);
		
	} while (ps->_GameStatus == OK);

}

void GameEnd(pSnake ps)
{
	switch (ps->_GameStatus)
	{
		case WALLS:
			SetsPos(24,10);
			printf("你撞墙了");
			Sleep(1000);
			break;
		case BITE:
			SetsPos(24, 10);
			printf("你咬住自己了");
			Sleep(1000);
			break;
		case END:
			SetsPos(24, 10);
			printf("游戏结束！");
			Sleep(1000);
			break;
	}
	pSnakeNode cur = ps->_pSnake;
	
	while (ps->_pSnake)
	{
		ps->_pSnake = cur->next;
		free(cur);
		cur = ps->_pSnake;
	}
	
}

